home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / Manuels & Misc / Assembly / AOA.ZIP / CH15 / TS.ASM < prev   
Encoding:
Assembly Source File  |  1996-03-26  |  7.7 KB  |  366 lines

  1. ;****************************************************************************
  2. ;
  3. ; TS:     A "Text Statistics" package which demonstrates the use of the UCR
  4. ;    Standard Library Package.
  5. ;
  6. ; Note:    The purpose of this program is not to demonstrate blazing fast
  7. ;    assembly code (it's not particularly fast) but rather to demonstrate
  8. ;    how easy it is to write assembly code using the standard library
  9. ;    and MASM 6.0.
  10. ;
  11. ; Randall Hyde
  12. ; 10/2/91
  13. ;
  14. ;***************************************************************************
  15. ;
  16. ;  The following include must be outside any segment and before the
  17. ;  ZZZZZZSEG segment.  It includes all the macro definitions for the
  18. ;  UCR Standard Library.
  19. ;
  20.         include     stdlib.a    ;Links into the UCR Standard
  21.         includelib    stdlib.lib    ; Library package.
  22. ;
  23. ;
  24. dseg        segment    para public 'data'
  25. ;
  26. WordCount    dw    0        ;Holds file word count value
  27. LineCnt        dw    0        ;Holds # of lines in file
  28. ControlCnt    dw    0        ;Counts # of control characters
  29. Punct        dw      0        ;Counts # of punctuation characters
  30. AlphaCnt    dw    0        ;Counts # of alphabetic characters
  31. NumericCnt    dw    0        ;Counts numeric digits in file
  32. Other        dw    0        ;Counts other chars in file
  33. MemorySize    dw    0        ;# of paragraphs of free memory
  34. Chars        dw    0        ;Total number of chars in file
  35. TotalChars    dq    0.0        ;FP version of the above
  36. FileHandle    dw    0        ;STDLIB file handle
  37. Const100    dd    100.0
  38. ;
  39. ;
  40. ; Create some sets to use in this program:
  41. ;
  42.         set    CharSet,Alphabetic,Punctuation,Control
  43. ;
  44. ;
  45. ; Character Counter array.  CharCnt [ch] contains the number of "ch"
  46. ; characters appearing in the file.
  47. ;
  48. CharCnt        dw    256 dup (0)
  49. ;
  50. ; Boolean flag to denote in/not in a word:
  51. ;
  52. InWord        db    0
  53. ;
  54. dseg        ends
  55. ;
  56. ;
  57. cseg        segment    para public 'code'
  58.         assume    cs:cseg, ds:dseg
  59.  
  60. ; Some useful constants-
  61.  
  62. EOFError    equ    8
  63.  
  64.  
  65.  
  66. ; Okay, here's the main program which does the job:
  67.  
  68. TS        proc
  69.         mov    ax, seg dseg        ;Set up the segment registers
  70.         mov    ds, ax
  71.         mov    es, ax
  72. ;
  73. ; Initialize the memory manager, giving all free memory to the heap.
  74. ;
  75.         meminit
  76.         mov    MemorySize, cx        ;Save # of available paragraphs.
  77. ;
  78. ; Set up the character sets:
  79. ;
  80. ;  First, build the Alphabetic set:
  81. ;
  82.         mov    al, "A"
  83.         mov    ah, "Z"
  84.         lesi    Alphabetic
  85.         RangeSet
  86.         AddStrL
  87.         db    "abcdefghijklmnopqrstuvwxyz",0
  88. ;
  89. ; Create the set with the punctuation characters:
  90. ;
  91.         lesi    Punctuation
  92.         AddStrL
  93.         db    "!@#$%^&*()_-+={[}]|\':;<,>.?/~`", '"', 0
  94. ;
  95. ; Create the control character set:
  96. ;
  97.         lesi    Control
  98.         mov    al,0
  99.         mov    ah, 1fh
  100.         RangeSet
  101.         mov    al, 7fh
  102.         AddChar
  103. ;
  104. ;
  105. ; Print the amount of available memory.
  106. ;
  107.         printf
  108.         db    "Text Statistics Program",cr,lf
  109.         db    "There are %d paragraphs of memory available",cr,lf,0
  110.         dd    MemorySize
  111. ;
  112. ; Get the filename off the command line:
  113. ;
  114.         argc
  115.         cmp    cx, 1
  116.         je    GoodCmdLine
  117.         print
  118.         db    cr,lf
  119.         db    "Missing file name!",cr,lf
  120.         db    "Usage: TS <filename>",cr,lf,0
  121.         jmp    Return2DOS
  122. ;
  123. GoodCmdLine:    mov    ax, 1
  124.         argv                ;Get the filename.
  125. ;
  126. ; Open the file.
  127. ;
  128.         mov    al, 0            ;Open for reading.
  129.         fopen                ;Open the file.
  130.         jnc    GoodOpen
  131. ;
  132. ; If the carry flag comes back set, we've got an error, print an appropriate
  133. ; message and quit:
  134. ;
  135.         print
  136.         db    "DOS error #",0
  137.         puti                ;Error code is in AX.
  138.         putcr
  139.         jmp    Return2DOS
  140. ;
  141. ; If the carry flag comes back clear, we've successfully opened the file.
  142. ; AX contains the STDLIB filehandle, ES:DI still points at the filename
  143. ; allocated on the heap:
  144. ;
  145. GoodOpen:    mov    FileHandle, AX        ;Save STDLIB file handle.
  146.         print
  147.         db    "Computing text statistics for ",0
  148.         puts                ;Print filename
  149.         free                ;Dispose of space on heap
  150.         putcr
  151.         putcr
  152. ;
  153. ; The following loops check for transitions between words and delimiters.
  154. ; Each time we go from "not a word" -> "word" this code bumps up the word
  155. ; count by one.
  156. ;
  157.         mov    ax, FileHandle
  158.         fReadOn
  159. ;
  160. TSLoop:        getc
  161.         jnc    NoError
  162.         jmp    ReadError
  163. ;
  164. ; See if the character is alphabetic
  165. ;
  166. NoError:    lesi    Alphabetic         ;Set contains A-Z, a-z
  167.         Member
  168.         jz    NotAlphabetic
  169.         inc    AlphaCnt
  170.         jmp    StatDone
  171. ;
  172. ; See if the character is a digit:
  173. ;
  174. NotAlphabetic:    cmp    al, "0"
  175.         jb    NotNumeric
  176.         cmp    al, "9"
  177.         ja    NotNumeric
  178.         inc    NumericCnt
  179.         jmp    StatDone
  180. ;
  181. ; See if the character is a punctuation character
  182. ;
  183. NotNumeric:    lesi    Punctuation
  184.         Member
  185.         jz    NotPunctuation
  186.         inc    Punct
  187.         jmp    StatDone
  188. ;
  189. ; See if this is a control character:
  190. ;
  191. NotPunctuation:    lesi    Control
  192.         Member
  193.         jz    NotControl
  194.         inc    ControlCnt
  195.         jmp    StatDone
  196. ;
  197. NotControl:    inc    Other
  198. StatDone:       mov    bl, al        ;Use char as index into CharCnt
  199.         mov    bh, 0
  200.         shl    bx, 1        ;Convert word index to byte index
  201.         inc    CharCnt [bx]
  202. ;
  203. ; Count lines and characters here:
  204. ;
  205.         cmp    al, lf
  206.         jne    NotNewLine
  207.         inc    LineCnt
  208. ;
  209. NotNewLine:     inc    Chars
  210. ;
  211. ; Count words down here
  212. ;
  213.         cmp    InWord, 0        ;See if we're in a word.
  214.         je    NotInAWord
  215.         cmp    al, " "
  216.         ja    WCDone
  217.         mov    InWord, 0        ;Just left a word
  218.         jmp    WCDone
  219. ;
  220. NotInAWord:    cmp    al, " "
  221.         jbe    WCDone
  222.         mov    InWord, 1        ;Just entered a word
  223.         inc    WordCount
  224. ;
  225. WCDone:
  226. ;
  227. ; Okay, or the current character into the character set so we can keep
  228. ; track of the characters which appear in this file.
  229. ;
  230.         lesi    CharSet
  231.         AddChar
  232.         jmp    TSLoop
  233. ;
  234. ;
  235. ; Come down here on EOF or other read error.
  236. ;
  237. ReadError:    cmp    ax, EOFError
  238.         je    Quit
  239.         print
  240.         db    "DOS Error ",0
  241.         puti
  242.         putcr
  243.         jmp    Return2DOS
  244. ;
  245. ; Return to DOS.
  246. ;
  247. Quit:        freadoff
  248.         mov    ax, FileHandle
  249.         fclose
  250.         printf
  251.         db    cr,lf,lf
  252.         db    "Number of words in this file is %d",cr,lf
  253.         db    "Number of lines in this file is %d",cr,lf
  254.         db    "Number of control characters is %d",cr,lf
  255.         db    "Number of punctuation characters is %d",cr,lf
  256.         db    "Number of alphabetic characters is %d",cr,lf
  257.         db    "Number of numeric characters is %d",cr,lf
  258.         db    "Number of other characters is %d",cr,lf
  259.         db    "Total number of characters is %d",cr,lf
  260.         db    lf, 0
  261.         dd    WordCount,LineCnt,ControlCnt,Punct
  262.         dd    AlphaCnt,NumericCnt,Other,Chars
  263. ;
  264. ; Print the characters that actually appeared in the file.
  265. ;
  266.         lesi    CharSet
  267. EC64:        mov    cx, 64            ;Chars/line on output.
  268. EachChar:    RmvItem
  269.         cmp    al, 0
  270.         je    CSDone
  271.         cmp    al, " "
  272.         jbe    EachChar
  273.         putc
  274.         loop    EachChar
  275.         putcr
  276.         jmp    EC64
  277. ;
  278. CSDone:        print
  279.         db    cr,lf,lf
  280.         db    "Press any key to continue:",0
  281.         getc
  282.         putcr
  283.         putcr
  284. ;
  285. ; Now print the statistics for each character:
  286. ;
  287.         mov    ax, Chars        ;Get character count,
  288.         utof                ; convert it to a floating
  289.         lesi    TotalChars        ; point value, and save this
  290.         sdfpa                ; value in "TotalChars".
  291. ;
  292. ; Print out each character, the number of occurrences, and the ratio of
  293. ; this character's count to the total number of characters.
  294. ;
  295.         mov    bx, " "*2        ;Start output with spaces.
  296. ComputeRatios:    cmp    CharCnt[bx], 0
  297.         je    SkipThisChar
  298.         mov    ax, bx
  299.         shr    ax, 1            ;Convert index to character
  300.         putc                ; and print it.
  301.         print
  302.         db    " = ",0
  303.         mov    ax, CharCnt [bx]
  304.         mov    cx, 4
  305.         putisize
  306.         print
  307.         db    "  Percentage of total is ",0
  308. ;
  309.         utof
  310. ;
  311. ; Divide by the total number of characters in the file:
  312. ;
  313.         lesi    TotalChars
  314.         ldfpo
  315.         fpdiv
  316. ;
  317. ; Multiply by 100 to get a percentage
  318. ;
  319.         lesi    Const100
  320.         lsfpo
  321.         fpmul
  322. ;
  323. ; Print the ratio:
  324. ;
  325.         mov    al, 7
  326.         mov    ah, 3
  327.         ftoam
  328.         puts
  329.         free
  330.         print
  331.         db    "%   ",cr,lf,0
  332. ;
  333. SkipThisChar:    inc    bx
  334.         inc    bx
  335.         cmp    bx, 200h
  336.         jb      ComputeRatios
  337.         putcr
  338. ;
  339. Return2DOS:    mov     ah, 4ch
  340.         int     21h
  341. ;
  342. ;
  343. TS        endp
  344. ;
  345. ;
  346. ;
  347. cseg            ends
  348. ;
  349. ;
  350. ; Allocate a reasonable amount of space for the stack (2k).
  351. ;
  352. sseg        segment    para stack 'stack'
  353. stk        db    256 dup ("stack   ")
  354. sseg        ends
  355. ;
  356. ;
  357. ;
  358. ; zzzzzzseg must be the last segment that gets loaded into memory!
  359. ; The UCR Standard Library package uses this segment to determine where
  360. ; the end of the program lies.
  361. ;
  362. zzzzzzseg    segment    para public 'zzzzzz'
  363. LastBytes    db    16 dup (?)
  364. zzzzzzseg    ends
  365.         end    TS
  366.